home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / scheme / pcscheme / geneva / sources.exe / SOURCES / C / GRAPHICS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-24  |  12.9 KB  |  486 lines

  1. /* GRAPHICS.C
  2.  ************************************************************************
  3.  *                                    *
  4.  *        PC Scheme/Geneva 4.00 Borland C code            *
  5.  *                                    *
  6.  * (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT        *
  7.  * (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva    *
  8.  *                                    *
  9.  *----------------------------------------------------------------------*
  10.  *                                    *
  11.  *            Graphics Primitives                *
  12.  *                                    *
  13.  *----------------------------------------------------------------------*
  14.  *                                    *
  15.  * Created by: L. Bartholdi        Date: 3 Jun 1992        *
  16.  * Revision history:                            *
  17.  * - 18 Jun 92:    Renaissance (Borland Compilers, ...)            *
  18.  *                                    *
  19.  *                    ``In nomine omnipotentii dei''    *
  20.  ************************************************************************/
  21.  
  22. #include    <stdarg.h>
  23. #include    <stdlib.h>
  24. #include    <graphics.h>
  25. #include    <setjmp.h>
  26. #include    "scheme.h"
  27.  
  28. extern void far    *_Cdecl _DDO_ADD;        /* BGI state detect addresses */
  29. extern "C" {
  30. void far    _GraphNotInstalled( void );
  31. }
  32.  
  33. void far    ErrorBGI( void );        /* Our BGI error handler */
  34. static jmp_buf    jumper;
  35.  
  36. #undef    outtext                    /* this is a BGI routine, too */
  37.  
  38. #define    NUMARGS    62
  39.  
  40. typedef    union {
  41.     char    *s;
  42.     REGPTR    r;
  43.     long    i;
  44.     }
  45.     GRAPHARG;
  46.  
  47. typedef    struct {
  48.     char    opcode;
  49.     void    far *disp;
  50.     } FARJUMP;
  51.  
  52. void    dopoly( REGPTR arg, void (far *proc)(int, const int far *) )
  53. {
  54. #define    MAXPOLY    401                /* seems acceptable ... */
  55.     typedef struct {
  56.         int    x, y;
  57.     }    POLYG;
  58.     POLYG    *poly;
  59.     int    len = 0;
  60.  
  61.     for( tmp_reg = *arg; tmp_reg.page; take_cdr(&tmp_reg), len++ );
  62.     if (!(poly = (POLYG *) malloc(4 * len)))
  63.         malloc_error("dopoly");
  64.  
  65.     for( len = 0 ; arg->page; take_cdr(arg), len++ )
  66.     {
  67.         tmp_reg = *arg, take_car(&tmp_reg);
  68.         tm2_reg = tmp_reg, take_car(&tm2_reg), take_cdr(&tmp_reg);
  69.         poly[len].x = tm2_reg.disp;
  70.         poly[len].y = tmp_reg.disp;
  71.     }
  72.     (*proc)( len, (int *) poly );
  73.     free( poly );
  74. }
  75.  
  76. /* If you have to add a new function, add it in the right class and    */
  77. /* increment the base ID of next classes in order to avoid        */
  78. /* duplicate case in the switch statement. Don't forget to update    */
  79. /* the similar table in graphics.s !                    */
  80.  
  81. #define    CONTROL(x)    ( 00 + (x) )        /* Control    func IDs */
  82. #define    DRAWING(x)    ( 20 + (x) )        /* Drawing    func IDs */
  83. #define    FILLING(x)    ( 40 + (x) )        /* Filling    func IDs */
  84. #define    WINDOWS(x)    ( 60 + (x) )        /* Windows     func IDs */
  85. #define    TEXTCHR(x)    ( 80 + (x) )        /* Text .CHR    func IDs */
  86. #define    PALETTE(x)    ( 100 + (x) )        /* Palette    func IDs */
  87. #define    QUERIES(x)    ( 120 + (x) )        /* State query    func IDs */
  88.  
  89. #define DOERROR(x)    ( 140 + (x) )        /* Error simul. func IDs */
  90.  
  91. int    graphit( int n_args, ...)
  92. {
  93.     char        argMalloc[NUMARGS];
  94.     GRAPHARG    carg[NUMARGS];
  95.     REGPTR        sarg;
  96.     REGPTR        sresult;
  97.     REG        f1 = FIXNUM(0), f2 = FIXNUM(0);
  98.     int        i, j;
  99.     va_list        vlist;
  100.     static        lasterror;
  101.     void far    *farstr;
  102.  
  103.     va_start(vlist, n_args);        /* skip until first argument */
  104.     for (i = 0; i < n_args; i++)         /* Warning: this structure may be wrong */
  105.         sarg = va_arg(vlist, REGPTR);    /* optimized (don't use i--)... (Thanks Borland) */
  106.     carg[0].i = int2long(sarg);
  107.     argMalloc[0] = 0;
  108.     va_end(vlist);
  109.  
  110.     va_start(vlist, n_args);        /* Convert every regptr */
  111.     for (i = 1; i < n_args; i++) {        /* Warning: this structure may be wrong */
  112.                         /* optimized (don't use i--)... (Thanks Borland) */
  113.         sarg = va_arg(vlist, REGPTR);
  114.         switch (ptype[CORRPAGE(sarg->page)]) {
  115.         case STRTYPE:
  116.             if ( carg[0].i == WINDOWS( 8 ) ) { /* put-image */
  117.                 farstr = reg2c(sarg)->string.buffer;
  118.                 argMalloc[n_args-i] = 0;
  119.             } else {                 /* not put-image */
  120.                 carg[n_args-i].s = string_asciz(sarg);
  121.                 argMalloc[n_args-i] = 1;
  122.             }
  123.             break;
  124.         case BIGTYPE:
  125.         case FIXTYPE:
  126.             carg[n_args-i].i = int2long(sarg);
  127.             argMalloc[n_args-i] = 0;
  128.             break;
  129.         default:
  130.             carg[n_args-i].r = sarg;
  131.             argMalloc[n_args-i] = 0;
  132.         }
  133.     }
  134.     sresult = va_arg(vlist, REGPTR); /* first arg was pushed first, so now it it the last arg... */
  135.     va_end(vlist);
  136.  
  137.     if ( _DDO_ADD == &_GraphNotInstalled )    /* avoid abnormal exit */
  138.     {
  139.         _DDO_ADD = &ErrorBGI;
  140.  
  141.         /* patch _GraphNotInstalled. That's dirty, but
  142.            a bug in graphics is graphdefaults() always calls _GNI */
  143.         ((FARJUMP far *) _GraphNotInstalled)->opcode = 0xea;
  144.         ((FARJUMP far *) _GraphNotInstalled)->disp = &ErrorBGI;
  145.  
  146.     }
  147.  
  148.     sresult->page = ADJPAGE(SPECFIX);    /* assume we'll return this */
  149.  
  150.     switch( (i = setjmp( jumper )) == 0 ? carg[0].i : i )   /* ie func */
  151.     {
  152.     case CONTROL( 0 ):
  153.         closegraph();
  154.         break;
  155.     case CONTROL( 1 ):
  156.         detectgraph( &((int) f1.disp), &((int) f2.disp) );
  157.         cons( sresult, &f1, &f2 );
  158.         break;
  159.     case CONTROL( 2 ):
  160.         graphdefaults();
  161.         break;
  162.     case CONTROL( 3 ):
  163.         sresult->disp = getgraphmode();
  164.         break;
  165.     case CONTROL( 4 ):
  166.              getmoderange( carg[1].i, &((int) f1.disp), &((int) f2.disp) );
  167.         cons( sresult, &f1, &f2 );
  168.         break;
  169.     case CONTROL( 5 ):
  170.         initgraph( (int *) &(carg[1].i), (int *) &(carg[2].i), carg[3].s );
  171.         break;
  172.     case CONTROL( 6 ):
  173.         sresult->disp = installuserdriver( carg[1].s, NULL );
  174.         break;
  175.     case CONTROL( 7 ):
  176.         sresult->disp = installuserfont( carg[1].s );
  177.         break;
  178.     case CONTROL( 8 ):
  179.         restorecrtmode();
  180.         break;
  181.     case CONTROL( 9 ):
  182.         setgraphmode( carg[1].i );
  183.         break;
  184.     case CONTROL( 10 ):
  185.         setwritemode( carg[1].i );
  186.         break;
  187.  
  188.     case DRAWING( 0 ):
  189.         arc( carg[1].i, carg[2].i, carg[3].i, carg[4].i, carg[5].i );
  190.         longjmp( jumper, DRAWING( 4 ) );
  191.     case DRAWING( 1 ):
  192.         circle( carg[1].i, carg[2].i, carg[3].i );
  193.         break;
  194.     case DRAWING( 2 ):
  195.         dopoly( carg[1].r, drawpoly );
  196.         break;
  197.     case DRAWING( 3 ):
  198.         ellipse( carg[1].i, carg[2].i, carg[3].i, carg[4].i, carg[5].i, carg[6].i );
  199.     case DRAWING( 4 ):
  200.         {
  201.         struct arccoordstype info;
  202.         getarccoords( &info );
  203.         f1.disp = info.xend, f2.disp = info.yend, cons( &tmp_reg, &f1, &f2 );
  204.         cons( sresult, &tmp_reg, &nil_reg );
  205.         f1.disp = info.xstart, f2.disp = info.ystart, cons( &tmp_reg, &f1, &f2 );
  206.         cons( sresult, &tmp_reg, sresult );
  207.         f1.disp = info.x, f2.disp = info.y, cons( &tmp_reg, &f1, &f2 );
  208.         cons( sresult, &tmp_reg, sresult );
  209.         }
  210.         break;
  211.     case DRAWING( 5 ):
  212.         {
  213.         long    l1 = 0, l2 = 0;
  214.              getaspectratio( (int *)&l1, (int *)&l2 );
  215.         long2int( &f1, l1 ), long2int( &f2, l2 );
  216.         cons( sresult, &f1, &f2 );
  217.         }
  218.         break;
  219.     case DRAWING( 6 ):
  220.         {
  221.         struct linesettingstype info;
  222.         long    l1 = 0;
  223.         getlinesettings( &info );
  224.         f1.disp = info.thickness, cons( sresult, &f1, &nil_reg );
  225.         l1 = info.upattern, long2int( &f1, l1), cons( sresult, &f1, sresult );
  226.         f1.disp = info.linestyle, cons( sresult, &f1, sresult );
  227.         }
  228.         break;
  229.     case DRAWING( 7 ):
  230.         line( carg[1].i, carg[2].i, carg[3].i, carg[4].i );
  231.         break;
  232.     case DRAWING( 8 ):
  233.         linerel( carg[1].i, carg[2].i );
  234.         break;
  235.     case DRAWING( 9 ):
  236.         lineto( carg[1].i, carg[2].i );
  237.         break;
  238.     case DRAWING( 10 ):
  239.         moveto( carg[1].i, carg[2].i );
  240.         break;
  241.     case DRAWING( 11 ):
  242.         moverel( carg[1].i, carg[2].i );
  243.         break;
  244.     case DRAWING( 12 ):
  245.         rectangle( carg[1].i, carg[2].i, carg[3].i, carg[4].i );
  246.         break;
  247.     case DRAWING( 13 ):
  248.         setaspectratio( carg[1].i, carg[2].i );
  249.         break;
  250.     case DRAWING( 14 ):
  251.         setlinestyle( carg[1].i, carg[2].i, carg[3].i );
  252.         break;
  253.  
  254.     case FILLING( 0 ):
  255.         bar( carg[1].i, carg[2].i, carg[3].i, carg[4].i );
  256.         break;
  257.     case FILLING( 1 ):
  258.         bar3d( carg[1].i, carg[2].i, carg[3].i, carg[4].i, carg[5].i, carg[6].i );
  259.         break;
  260.     case FILLING( 2 ):
  261.         fillellipse( carg[1].i, carg[2].i, carg[3].i, carg[4].i );
  262.         break;
  263.     case FILLING( 3 ):
  264.         dopoly( carg[1].r, fillpoly );
  265.         break;
  266.     case FILLING( 4 ):
  267.         floodfill( carg[1].i, carg[2].i, carg[3].i );
  268.         break;
  269.     case FILLING( 5 ):
  270.         {
  271.         char    s[8];
  272.         getfillpattern( s );
  273.         alloc_block( sresult, STRTYPE, 8 );
  274.         put_str( s, CORRPAGE(sresult->page), sresult->disp );
  275.         }
  276.         break;
  277.     case FILLING( 6 ):
  278.         {
  279.         struct fillsettingstype    fillinfo;
  280.         getfillsettings( &fillinfo );
  281.         f1.disp = fillinfo.pattern, f2.disp = fillinfo.color;
  282.         cons( sresult, &f1, &f2 );
  283.         }
  284.         break;
  285.     case FILLING( 7 ):
  286.         pieslice( carg[1].i, carg[2].i, carg[3].i, carg[4].i, carg[5].i );
  287.         break;
  288.     case FILLING( 8 ):
  289.         sector( carg[1].i, carg[2].i, carg[3].i, carg[4].i, carg[5].i, carg[6].i );
  290.         break;
  291.     case FILLING( 9 ):
  292.         {
  293.         char    pattern[8];
  294.         int    count;
  295.  
  296.         tmp_reg = *carg[1].r;
  297.         for( count = 0; count < 8; take_cdr(&tmp_reg), count++ )
  298.         {
  299.             if ( tmp_reg.page == nil_reg.page )
  300.                 tmp_reg = *carg[1].r;
  301.             tm2_reg = tmp_reg; take_car(&tm2_reg);
  302.             pattern[count] = tm2_reg.disp;
  303.         }
  304.         setfillpattern( pattern, carg[2].i );
  305.         }
  306.         break;
  307.     case FILLING( 10 ):
  308.         setfillstyle( carg[1].i, carg[2].i );
  309.         break;
  310.  
  311.     case WINDOWS( 0 ):
  312.         cleardevice();
  313.         break;
  314.     case WINDOWS( 1 ):
  315.         setactivepage( carg[1].i );
  316.         break;
  317.     case WINDOWS( 2 ):
  318.         setvisualpage( carg[1].i );
  319.         break;
  320.     case WINDOWS( 3 ):
  321.         clearviewport();
  322.         break;
  323.     case WINDOWS( 4 ):
  324.         {
  325.         struct viewporttype    viewinfo;
  326.         getviewsettings( &viewinfo );
  327.         f1.disp = viewinfo.clip, cons( sresult, &f1, &nil_reg );
  328.         f1.disp = viewinfo.right, f2.disp = viewinfo.bottom;
  329.         cons( &tmp_reg, &f1, &f2 );
  330.         cons( sresult, &tmp_reg, sresult );
  331.         f1.disp = viewinfo.left, f2.disp = viewinfo.top;
  332.         cons( &tmp_reg, &f1, &f2 );
  333.         cons( sresult, &tmp_reg, sresult );
  334.         }
  335.         break;
  336.     case WINDOWS( 5 ):
  337.         setviewport( carg[1].i, carg[2].i, carg[3].i, carg[4].i, carg[5].i );
  338.         break;
  339.     case WINDOWS( 6 ):
  340.         alloc_block( sresult, STRTYPE, imagesize( carg[1].i, carg[2].i, carg[3].i, carg[4].i ) );
  341.         getimage( carg[1].i, carg[2].i, carg[3].i, carg[4].i, reg2c(sresult)->string.buffer );
  342.         break;
  343.     case WINDOWS( 7 ):
  344.         long2int( sresult, imagesize( carg[1].i, carg[2].i, carg[3].i, carg[4].i ) );
  345.         break;
  346.     case WINDOWS( 8 ):
  347.         putimage( carg[1].i, carg[2].i, farstr, carg[4].i );
  348.         break;
  349.     case WINDOWS( 9 ):
  350.         sresult->disp = getpixel( carg[1].i, carg[2].i );
  351.         break;
  352.     case WINDOWS( 10 ):
  353.         putpixel( carg[1].i, carg[2].i, carg[3].i );
  354.         break;
  355.  
  356.     case TEXTCHR( 0 ):
  357.         {
  358.         struct textsettingstype    textinfo;
  359.         gettextsettings( &textinfo );
  360.         f1.disp = textinfo.vert, cons( sresult, &f1, &nil_reg );
  361.         f1.disp = textinfo.horiz, cons( sresult, &f1, sresult );
  362.         f1.disp = textinfo.charsize, cons( sresult, &f1, sresult );
  363.         f1.disp = textinfo.direction, cons( sresult, &f1, sresult );
  364.         f1.disp = textinfo.font, cons( sresult, &f1, sresult );
  365.         }
  366.         break;
  367.     case TEXTCHR( 1 ):
  368.         outtext( carg[1].s );
  369.         break;
  370.     case TEXTCHR( 2 ):
  371.         outtextxy( carg[1].i, carg[2].i, carg[3].s );
  372.         break;
  373.     case TEXTCHR( 3 ):
  374.         settextjustify( carg[1].i, carg[2].i );
  375.         break;
  376.     case TEXTCHR( 4 ):
  377.         settextstyle( carg[1].i, carg[2].i, carg[3].i );
  378.         break;
  379.     case TEXTCHR( 5 ):
  380.         setusercharsize( carg[1].i, carg[2].i, carg[3].i, carg[4].i );
  381.         break;
  382.     case TEXTCHR( 6 ):
  383.         sresult->disp = textheight( carg[1].s );
  384.         break;
  385.     case TEXTCHR( 7 ):
  386.         sresult->disp = textwidth( carg[1].s );
  387.         break;
  388.  
  389.     case PALETTE( 0 ):
  390.         sresult->disp = getbkcolor();
  391.         break;
  392.     case PALETTE( 1 ):
  393.         sresult->disp = getcolor();
  394.         break;
  395.     case PALETTE( 2 ):
  396.         {
  397.         struct palettetype far *pal = getdefaultpalette();
  398.         *sresult = nil_reg;
  399.         for( int i = pal->size-1; i >= 0; i-- )
  400.             f1.disp = pal->colors[i], cons( sresult, &f1, sresult );
  401.         }
  402.         break;
  403.     case PALETTE( 3 ):
  404.         sresult->disp = getmaxcolor();
  405.         break;
  406.     case PALETTE( 4 ):
  407.         {
  408.         struct palettetype pal;
  409.         getpalette(&pal);
  410.         *sresult = nil_reg;
  411.         for( int i = pal.size-1; i >= 0; i-- )
  412.             f1.disp = pal.colors[i], cons( sresult, &f1, sresult );
  413.         }
  414.         break;
  415.     case PALETTE( 5 ):
  416.         sresult->disp = getpalettesize();
  417.         break;
  418.     case PALETTE( 6 ):
  419.         {
  420.         struct palettetype pal;
  421.         for( pal.size = 0; carg[1].r->page; take_cdr(carg[1].r), pal.size++ )
  422.         {
  423.             tmp_reg = *carg[1].r, take_car( &tmp_reg );
  424.             pal.colors[pal.size] = tmp_reg.disp;
  425.         }
  426.         setallpalette( &pal );
  427.         }
  428.         break;
  429.     case PALETTE( 7 ):
  430.         setbkcolor( carg[1].i );
  431.         break;
  432.     case PALETTE( 8 ):
  433.         setcolor( carg[1].i );
  434.         break;
  435.     case PALETTE( 9 ):
  436.         setpalette( carg[1].i, carg[2].i );
  437.         break;
  438.     case PALETTE( 10 ):
  439.         setrgbpalette( carg[1].i, carg[2].i, carg[3].i, carg[4].i );
  440.         break;
  441.  
  442.     case QUERIES( 0 ):
  443.         alloc_string( sresult, grapherrormsg( carg[1].i ) );
  444.         break;
  445.     case QUERIES( 1 ):
  446.         sresult->disp = lasterror;
  447.         break;
  448.     case QUERIES( 2 ):
  449.         alloc_string( sresult, getdrivername() );
  450.         break;
  451.     case QUERIES( 3 ):
  452.         sresult->disp = getmaxmode();
  453.         break;
  454.     case QUERIES( 4 ):
  455.         f1.disp = getmaxx(), f2.disp = getmaxy();
  456.         cons( sresult, &f1, &f2 );
  457.         break;
  458.     case QUERIES( 5 ):
  459.         alloc_string( sresult, getmodename( carg[1].i ) );
  460.         break;
  461.     case QUERIES( 6 ):
  462.         f1.disp = getx(), f2.disp = gety();
  463.         cons( sresult, &f1, &f2 );
  464.         break;
  465.  
  466.     case DOERROR( 0 ):
  467.         return lasterror = grNoInitGraph;
  468.  
  469.     default:
  470.         return    -1;
  471.     }
  472.  
  473.     for ( i = 0; i < n_args; i++ ) {     /* Free space for dynamic args */
  474.         if ( argMalloc[i] )
  475.             free( carg[i].s );
  476.     }
  477.  
  478.     return    lasterror = graphresult();
  479.  
  480. }
  481.  
  482. void    ErrorBGI( void )        /* BGI error handler */
  483. {
  484.     longjmp( jumper, DOERROR( 0 ) );
  485. }
  486.